#include "SbotPlugin.h"

void SbotPlugin::run() {
    this->PluginInitAtThreadHook();
    while (!isStopped) {
        if (isPaused) {
            this->threadMutex.lock();
            this->threadCondition.wait(&this->threadMutex);
            this->threadMutex.unlock();
        }

        QCoreApplication::processEvents();
        this->PluginThreadLoop();
    }
}

int SbotPlugin::PluginQmlInit(QQmlEngine* engine) {
    const QString pluginQmlRes = this->pluginInfo.pluginQmlRes;

    if (pluginQmlRes == "") {
        qWarning() << "No qml resource found for " << this->pluginInfo.pluginName << " plugin";
        return SBT_ERR_NOTFOUND;
    }

    if (!engine) {
        qDebug() << "Invalid QQmlEngine provided.";
        return SBT_ERROR;
    }

    this->pluginUi = new QQmlComponent(engine);
    this->pluginUi->loadUrl(QUrl(pluginQmlRes));

    if (this->pluginUi->isError()) {
        qDebug() << "Plugin UI component has errors. Error string:" << pluginUi->errorString();
        delete this->pluginUi;
        this->pluginUi = nullptr;
        return SBT_ERROR;
    }

    if (!this->pluginUi) {
        qDebug() << "Plugin UI component is not initialized.";
        return SBT_ERROR;
    }

    this->qmlObj = this->pluginUi->create();
    if (this->qmlObj == nullptr) {
        qDebug() << "Failed to create QML object.";
        return SBT_ERROR;
    }

    //加载当前对象到qml中
    engine->rootContext()->setContextProperty(GetPluginInfo().pluginName, this);

    return SBT_NERR;
}

QObject* SbotPlugin::GetQmlObject() { return this->qmlObj; }

int SbotPlugin::PluginThreadStart() {
    if (!this->isRunning()) {
        this->isPaused = false;
        this->isStopped = false;
        this->start();
    }

    return 0;
}

int SbotPlugin::PluginThreadStop() {
    this->isStopped = true;

    if (this->isRunning()) {
        this->threadMutex.lock();
        this->threadCondition.wakeOne();
        this->threadMutex.unlock();
        this->quit();
        this->wait();  //等待线程结束
    }

    return 0;
}

int SbotPlugin::PluginThreadPause() {
    this->isPaused = true;
    return 0;
}

int SbotPlugin::PluginThreadResume() {
    this->isPaused = false;

    if (isRunning()) {
        this->threadMutex.lock();
        this->threadCondition.wakeOne();
        this->threadMutex.unlock();
    }

    return 0;
}

const SbotPluginInformation& SbotPlugin::GetPluginInfo() { return this->pluginInfo; }
